// ============================================================================
//
// Copyright (C) 2006-2007 Dengues
//
// Google Group: http://groups.google.com/group/dengues
// QQ Group: 24885404
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// ============================================================================
package org.dengues.warehouse.dbmanager.ui;

import java.sql.Connection;

import org.dengues.commons.IDenguesSharedImage;
import org.dengues.commons.utils.ImageUtil;
import org.dengues.core.metadata.DatabaseContainer;
import org.dengues.warehouse.i18n.Messages;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.ProgressIndicator;
import org.eclipse.jface.dialogs.TrayDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.MouseTrackListener;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Layout;
import org.eclipse.swt.widgets.Shell;

/**
 * Qiang.Zhang.Adolf@gmail.com class global comment. Detailled comment <br/>
 * 
 * $Id: Dengues.epf 1 2006-09-29 17:06:40Z qiang.zhang $
 * 
 */
public class DatabaseManagerDialog extends TrayDialog {

    private final DatabaseContainer container;

    private DatabaseNavigateTree databaseNavigateTree;

    private final IProgressMonitor progressMonitor = new NullProgressMonitor();

    private ContentComposite contentComposite;

    private ProgressIndicator progressIndicator;

    private final Image leftImage = ImageUtil.getImage(IDenguesSharedImage.DBINFO_LEFT);

    private final Image rightImage = ImageUtil.getImage(IDenguesSharedImage.DBINFO_RIGHT);

    private Composite areaContainer;

    private Composite sash;

    private static int leftWidth = 200;

    private final int rightWidth = 550;

    private static final int DEFAULT_SASH = 8;

    private Label button;

    private final Connection connection;

    /**
     * Qiang.Zhang.Adolf@gmail.com SqlQueryDialog constructor comment.
     * 
     * @param parentShell
     * @param container
     */
    public DatabaseManagerDialog(Shell parentShell, DatabaseContainer container, Connection connection) {
        super(parentShell);
        this.connection = connection;
        setShellStyle(SWT.APPLICATION_MODAL | SWT.DIALOG_TRIM);
        this.container = container;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
     */
    @Override
    protected void configureShell(Shell newShell) {
        super.configureShell(newShell);
        newShell.setSize(700, 450);
        newShell.setText(Messages.getString("SqlQueryDialog.Title.Name")); //$NON-NLS-1$
        newShell.setLocation(Display.getCurrent().getActiveShell().toDisplay(100, 100));

    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
     */
    @Override
    protected Control createDialogArea(Composite parent) {
        // create the top level composite for the dialog area
        areaContainer = new Composite(parent, SWT.NONE);
        GridLayout layout = new GridLayout(3, false);
        layout.marginHeight = 0;
        layout.marginWidth = 0;
        layout.marginBottom = 0;
        layout.marginTop = 0;
        layout.marginLeft = 0;
        layout.marginRight = 0;
        layout.verticalSpacing = 0;
        layout.horizontalSpacing = 0;
        areaContainer.setLayout(layout);
        GridData gridData = new GridData(GridData.FILL_BOTH);
        areaContainer.setLayoutData(gridData);
        areaContainer.setFont(parent.getFont());

        createLeft(areaContainer);
        createCenter(areaContainer);
        createRight(areaContainer);

        gridData = new GridData(GridData.FILL_VERTICAL);
        gridData.widthHint = rightWidth - DEFAULT_SASH * 2;
        contentComposite.setLayoutData(gridData);

        Label titleBarSeparator = new Label(areaContainer, SWT.HORIZONTAL | SWT.SEPARATOR);
        titleBarSeparator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

        return areaContainer;
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "createSash".
     * 
     * @return
     */
    private void createCenter(Composite parent) {
        sash = new Composite(parent, SWT.NONE);
        GridLayout layout = new GridLayout(1, false);
        layout.marginHeight = 0;
        layout.marginWidth = 0;
        layout.marginBottom = 0;
        layout.marginTop = 0;
        layout.marginLeft = 0;
        layout.marginRight = 0;
        layout.verticalSpacing = 0;
        layout.horizontalSpacing = 0;
        sash.setLayout(layout);
        GridData gridData2 = new GridData(GridData.FILL_VERTICAL);
        gridData2.widthHint = DEFAULT_SASH;
        sash.setLayoutData(gridData2);
        sash.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND));

        Composite butonComp = new Composite(sash, SWT.NONE);
        layout = new GridLayout(1, false);
        layout.marginHeight = 0;
        layout.marginWidth = 0;
        layout.marginBottom = 0;
        layout.marginTop = 0;
        layout.marginLeft = 0;
        layout.marginRight = 0;
        layout.verticalSpacing = 0;
        layout.horizontalSpacing = 0;
        butonComp.setLayout(layout);
        gridData2 = new GridData(GridData.FILL_VERTICAL);
        gridData2.verticalAlignment = GridData.CENTER;
        butonComp.setLayoutData(gridData2);
        butonComp.setCursor(new Cursor(getShell().getDisplay(), SWT.CURSOR_HAND));

        button = new Label(butonComp, SWT.NONE);
        button.setImage(leftImage);
        button.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_CENTER));
        button.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseUp(MouseEvent e) {
                if (button.getImage() == leftImage) {
                    leftWidth = databaseNavigateTree.getBounds().width;

                    databaseNavigateTree.setSize(0, databaseNavigateTree.getBounds().height);
                    databaseNavigateTree.setLocation(0, 0);

                    sash.setLocation(0, 0);

                    contentComposite.setSize(contentComposite.getBounds().width + leftWidth, contentComposite.getBounds().height);
                    contentComposite.setLocation(DEFAULT_SASH, 0);

                    button.setImage(rightImage);
                } else {
                    databaseNavigateTree.setSize(leftWidth, databaseNavigateTree.getBounds().height);
                    databaseNavigateTree.setLocation(0, 0);

                    sash.setLocation(leftWidth, 0);

                    contentComposite.setSize(contentComposite.getBounds().width - leftWidth, contentComposite.getBounds().height);
                    contentComposite.setLocation(DEFAULT_SASH + leftWidth, 0);

                    button.setImage(leftImage);
                }
                // areaContainer.layout(false);
                // areaContainer.getDisplay().update();
            }

        });
        HoverResizer hoverResizer = new HoverResizer();
        areaContainer.addControlListener(hoverResizer);
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "createRight".
     * 
     * @param composite
     */
    private void createRight(Composite composite) {
        contentComposite = new ContentComposite(composite, this);
        contentComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
        contentComposite.getSqlEditorComposite().setDatabaseContainer(container);
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "createLeft".
     * 
     * @param composite
     */
    private void createLeft(Composite composite) {
        databaseNavigateTree = new DatabaseNavigateTree(composite, connection);
        databaseNavigateTree.setDatabaseContainer(container);
        databaseNavigateTree.setSqlQueryDialog(this);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.dialogs.TrayDialog#createButtonBar(org.eclipse.swt.widgets.Composite)
     */
    @Override
    protected Control createButtonBar(Composite parent) {
        Composite composite = new Composite(parent, SWT.NONE);
        GridLayout layout = new GridLayout();
        layout.numColumns = 4;
        layout.marginWidth = 0;
        layout.marginHeight = 0;
        layout.horizontalSpacing = 0;
        composite.setLayout(layout);
        composite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
        composite.setFont(parent.getFont());

        // create help control if needed
        Control helpControl = createHelpControl(composite);
        ((GridData) helpControl.getLayoutData()).horizontalIndent = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);

        GridData gd = new GridData(GridData.FILL_HORIZONTAL);
        progressIndicator = new ProgressIndicator(composite);
        progressIndicator.setLayoutData(gd);

        // Control buttonSection = super.createButtonBar(composite);
        // ((GridData) buttonSection.getLayoutData()).grabExcessHorizontalSpace = true;
        return composite;
    }

    /**
     * Getter for progressMonitor.
     * 
     * @return the progressMonitor
     */
    public IProgressMonitor getProgressMonitor() {
        return this.progressMonitor;
    }

    /**
     * Getter for resultsComposite.
     * 
     * @return the resultsComposite
     */
    public ContentComposite getContentComposite() {
        return this.contentComposite;
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com DatabaseManagerDialog class global comment. Detailled comment <br/>
     * 
     * $Id: Dengues.epf 1 2006-09-29 17:06:40Z qiang.zhang $
     * 
     */
    class HoverResizer extends MouseAdapter implements MouseMoveListener, MouseTrackListener, ControlListener {

        boolean fIsDown = false;

        int fx;

        /**
         * Qiang.Zhang.Adolf@gmail.com HoverResizer constructor comment.
         */
        public HoverResizer() {
            sash.addMouseListener(this);
            sash.addMouseMoveListener(this);
            sash.addMouseTrackListener(this);
        }

        @Override
        public void mouseDown(MouseEvent e) {
            fIsDown = true;
            fx = e.x;
        }

        @Override
        public void mouseUp(MouseEvent e) {
            fIsDown = false;
            resize(e);
        }

        public void mouseMove(MouseEvent e) {
            if (fIsDown) {
                resize(e);
            }
        }

        private void resize(MouseEvent e) {
            int x2 = e.x;
            x2 = computeX(x2);
            int dx = x2 - fx;
            int width2 = contentComposite.getBounds().width - dx;
            int width = databaseNavigateTree.getBounds().width + dx;

            if (width > 0 && width2 > DEFAULT_SASH) {
                databaseNavigateTree.setSize(width, databaseNavigateTree.getBounds().height);
                databaseNavigateTree.setLocation(0, 0);

                sash.setLocation(databaseNavigateTree.getBounds().width, 0);

                contentComposite.setSize(width2, contentComposite.getBounds().height);
                contentComposite.setLocation(sash.getBounds().x + DEFAULT_SASH, contentComposite.getLocation().y);
            }

        }

        /**
         * Qiang.Zhang.Adolf@gmail.com Comment method "computeX".
         * 
         * @param x2
         * @return
         */
        private int computeX(int x2) {
            if (x2 >= getShell().getSize().x) {
                x2 = x2 + Short.MIN_VALUE;
                return computeX(x2);
            }
            return x2;
        }

        /*
         * (non-Javadoc)
         * 
         * @see org.eclipse.swt.events.MouseTrackListener#mouseEnter(org.eclipse.swt.events.MouseEvent)
         */
        public void mouseEnter(MouseEvent e) {
            if (button.getImage() == rightImage) {
                sash.setCursor(null);
            } else {
                sash.setCursor(new Cursor(getShell().getDisplay(), SWT.CURSOR_SIZEE));
            }

        }

        /*
         * (non-Javadoc)
         * 
         * @see org.eclipse.swt.events.MouseTrackListener#mouseExit(org.eclipse.swt.events.MouseEvent)
         */
        public void mouseExit(MouseEvent e) {

        }

        /*
         * (non-Javadoc)
         * 
         * @see org.eclipse.swt.events.MouseTrackListener#mouseHover(org.eclipse.swt.events.MouseEvent)
         */
        public void mouseHover(MouseEvent e) {

        }

        /*
         * (non-Javadoc)
         * 
         * @see org.eclipse.swt.events.ControlListener#controlMoved(org.eclipse.swt.events.ControlEvent)
         */
        public void controlMoved(ControlEvent e) {

        }

        /*
         * (non-Javadoc)
         * 
         * @see org.eclipse.swt.events.ControlListener#controlResized(org.eclipse.swt.events.ControlEvent)
         */
        public void controlResized(ControlEvent e) {

        }
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com DatabaseManagerDialog class global comment. Detailled comment <br/>
     * 
     * $Id: Dengues.epf 1 2006-09-29 17:06:40Z qiang.zhang $
     * 
     */
    class HoverLayout extends Layout {

        /*
         * (non-Javadoc)
         * 
         * @see org.eclipse.swt.widgets.Layout#computeSize(org.eclipse.swt.widgets.Composite, int, int, boolean)
         */
        @Override
        protected Point computeSize(Composite composite, int hint, int hint2, boolean flushCache) {
            return new Point(100, 100);
        }

        /*
         * (non-Javadoc)
         * 
         * @see org.eclipse.swt.widgets.Layout#layout(org.eclipse.swt.widgets.Composite, boolean)
         */
        @Override
        protected void layout(Composite composite, boolean flushCache) {

        }

    }

    /**
     * Getter for databaseNavigateTree.
     * 
     * @return the databaseNavigateTree
     */
    public DatabaseNavigateTree getDatabaseNavigateTree() {
        return this.databaseNavigateTree;
    }

}
